'use client'; import { useCallback, useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; import { ArrowLeft } from 'lucide-react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faStar as faStarSolid } from '@fortawesome/free-solid-svg-icons'; import { faStar as faStarRegular } from '@fortawesome/free-regular-svg-icons'; import useAuth from '@/hooks/useAuth'; import { fetchApi } from '@/lib/utils/client'; import { StockWatchStatusResponse, StockWatchToggleResponse } from '@/types/stock'; type Props = { code: string; name: string; }; // 종목 상세 상단 바 — 뒤로가기 + 관심종목(☆) 토글. RSC(page.tsx) 안에 마운트되는 client island. export default function StockDetailHeader({ code, name }: Props) { const router = useRouter(); const { isAuthenticated } = useAuth(); const [watched, setWatched] = useState(false); const [pending, setPending] = useState(false); // 초기 관심 여부 조회 (로그인 시) useEffect(() => { if (!isAuthenticated) { setWatched(false); return; } let alive = true; fetchApi(`/api/stocks/watchlist/status?codes=${encodeURIComponent(code)}`, { method: 'GET', silent: true }) .then(res => { if (alive && res.success && res.data) { setWatched(res.data.map?.[code] === true); } }) .catch(() => {}); return () => { alive = false; }; }, [code, isAuthenticated]); const handleBack = useCallback(() => { if (window.history.length > 1) { router.back(); } else { router.push('/stock'); } }, [router]); const handleToggle = useCallback(async () => { if (!isAuthenticated) { if (confirm('로그인 후 이용 가능합니다.\n로그인하시겠습니까?')) { window.dispatchEvent(new CustomEvent('auth:unauthorized')); } return; } if (pending) { return; } setPending(true); const next = !watched; setWatched(next); try { const res = await fetchApi(`/api/stocks/${encodeURIComponent(code)}/watch`, { method: 'POST', silent: true }); if (res.success && res.data) { setWatched(res.data.isWatched); window.dispatchEvent(new CustomEvent('watchlist:changed')); } else { setWatched(!next); } } catch { setWatched(!next); } finally { setPending(false); } }, [code, isAuthenticated, pending, watched]); return (
); }